package cn.lingyangwl.agile.auth.oauth2.support;

import cn.lingyangwl.agile.model.module.auth.GrantTypeEnum;
import cn.lingyangwl.agile.auth.model.CheckLoginParam;
import cn.lingyangwl.agile.auth.oauth2.Authentication;
import cn.lingyangwl.agile.auth.oauth2.model.RegisteredClient;
import cn.lingyangwl.agile.auth.utils.OAuth2Utils;
import cn.lingyangwl.agile.model.enums.AuthErrorEnum;
import cn.lingyangwl.agile.model.module.auth.LoginUser;
import cn.lingyangwl.agile.model.module.auth.OAuth2ParamKeys;
import cn.lingyangwl.framework.tool.core.exception.BizException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;

import javax.servlet.http.HttpServletRequest;

/**
 * @author shenguangyang
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class OAuth2GrantClient extends BaseOauth2Grant {

    @Override
    protected LoginUser authenticate(Authentication authentication) {
        throw new BizException("目前不支持客户端授权模式");
    }

    @Override
    protected GrantTypeEnum grantType() {
        return GrantTypeEnum.CLIENT_CREDENTIALS;
    }

    @Override
    protected void checkClient(RegisteredClient registeredClient) {
        assert registeredClient != null;
        if (!registeredClient.getAuthorizationGrantTypes().contains(GrantTypeEnum.CLIENT_CREDENTIALS.getCode())) {
            throw new BizException(AuthErrorEnum.OAUTH2_UNAUTHORIZED_CLIENT);
        }
    }

    @Override
    protected boolean isCheckCaptcha() {
        return false;
    }

    /**
     * 校验扩展参数 密码模式密码必须不为空
     * @param request 参数列表
     */
    @Override
    public void checkParams(HttpServletRequest request) {
        super.checkParams(request);
        MultiValueMap<String, String> parameters = OAuth2Utils.getParameters(request);
        String clientId = parameters.getFirst(OAuth2ParamKeys.CLIENT_ID);
        String clientSecret = parameters.getFirst(OAuth2ParamKeys.CLIENT_SECRET);

        CheckLoginParam checkLoginParam = CheckLoginParam.of(clientId, clientSecret).isAnyEmpty()
                .passwordLength().userNameLength();
        checkLoginParam.throwError((BizException::new));
    }
}
